#include "user_uart_obj.h"

// user head file
#include "usart.h"

/*
    说明：
    串口dma idle模式接收范例，用户可参考该范例来修改
*/


#define UART3_RX_FIFO_DEEP             UART_FIFO_SIZE_4        // 必须是2的幂次方
#define UART3_RX_FIFO_SINGLE_BUFF_SIZE 128

uart_obj_t uart_obj3 = {0};

uint8_t uart3_tx_buf[128] = {0};

uint8_t uart3_rx_fifo_buf[UART3_RX_FIFO_DEEP * UART3_RX_FIFO_SINGLE_BUFF_SIZE] = {0};

rx_fifo_manage_t uart3_rx_fifo_manage[UART3_RX_FIFO_DEEP] = {0};

void uart3_tx_port_cb(uint8_t* udata, uint16_t len);
void uart3_fifo_rx_cb(uint8_t* rdata, uint16_t len);
void uart3_fifo_rx_stop_cb(void);
void uart3_fifo_rx_start_cb(uint8_t* rx_data, uint16_t len);

void mid_uart_obj_init(void)
{
    // dma + idle 模式初始化
    uart_init_t uart_init = {
        .tx_buf_addr     = uart3_tx_buf,
        .uart_tx_port_cb = uart3_tx_port_cb,
        .tx_buf_size     = sizeof(uart3_tx_buf),

        .rx_time_out_set         = 5,
        .rx_fifo_buf_base_addr   = uart3_rx_fifo_buf,
        .rx_fifo_buf_size_single = UART3_RX_FIFO_SINGLE_BUFF_SIZE,
        .rx_fifo_buf_size_total  = UART3_RX_FIFO_DEEP * UART3_RX_FIFO_SINGLE_BUFF_SIZE,
        .rx_fifo_deep            = UART3_RX_FIFO_DEEP,

        .rx_fifo_manage = uart3_rx_fifo_manage,

        .uart_fifo_rx_cb       = uart3_fifo_rx_cb,
        .uart_fifo_rx_stop_cb  = uart3_fifo_rx_stop_cb,
        .uart_fifo_rx_start_cb = uart3_fifo_rx_start_cb,
    };
    uart_obj_dma_init(&uart_obj3, &uart_init);
}

void uart3_tx_port_cb(uint8_t* udata, uint16_t len)
{
    // HAL_UART_Transmit(&huart3, udata, len, 1000);
    HAL_UART_Transmit_DMA(&huart3, udata, len);
	while(huart3.gState != HAL_UART_STATE_READY)
	{};//等待发送完成
}

void uart3_fifo_rx_cb(uint8_t* rdata, uint16_t len)
{
    // 发出收到的数据
    uart_obj_tx_bin_data(&uart_obj3, rdata, len);
}

void uart3_fifo_rx_stop_cb(void)
{
    HAL_UART_DMAStop(&huart3);
}

void uart3_fifo_rx_start_cb(uint8_t* rx_data, uint16_t len)
{
    HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx_data, len);
    __HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
    __HAL_UART_CLEAR_FLAG(&huart3, UART_IT_IDLE);
    __HAL_UART_CLEAR_FLAG(&huart3, UART_IT_ORE);
}

/*-------------------------------------------HAL 库的串口dma 空闲中断------------------------------ */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
{
    if (huart == &huart3)
    {
        //接收完成，通知uart_obj
        uart_obj_dma_rx_idle_finish(&uart_obj3, Size);
    }
}

/*-------------------------------------------HAL 库的串口错误中断------------------------------ */
void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart)
{
    __HAL_UART_CLEAR_OREFLAG(huart);        // 清除ORE错误标志
    //必须加，发生错误时重新初始化
    if (huart == &huart3)
    {
        uart3_fifo_rx_start_cb(uart3_rx_fifo_buf, UART3_RX_FIFO_SINGLE_BUFF_SIZE);
    }
}

/*--------------------------------------------------需要对外调用的函数----------------------------------------------------------------*/
void mid_uart_read_task(void)
{
    uart_obj_rx_fifo_read(&uart_obj3);
}

